package com.aura.lyngen.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.aura.lyngen.exception.ErrorCode;
import com.aura.lyngen.exception.ThrowUtils;
import com.aura.lyngen.manager.CosManager;
import com.aura.lyngen.service.ScreenshotService;
import com.aura.lyngen.utils.WebScreenshotUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;

@Slf4j
@Service
public class ScreenShotServiceImpl implements ScreenshotService {

    @Resource
    private CosManager cosManager;

    // 移除 Executor 依赖，直接使用虚拟线程

    @Override
    public String generateAndUploadScreenshot(String webUrl) throws ExecutionException, InterruptedException {
        // 参数校验
        ThrowUtils.throwIf(StrUtil.isBlank(webUrl), ErrorCode.PARAMS_NULL, "截图的网址不能为空");
        log.info("开始异步生成网页截图，URL：{}", webUrl);

        try {
            // 使用 JDK 21 虚拟线程执行截图任务
            CompletableFuture<String> screenshotFuture = CompletableFuture.supplyAsync(() -> {
                return WebScreenshotUtils.saveWebPageScreenshot(webUrl);
            }, Executors.newVirtualThreadPerTaskExecutor());

            // 等待截图生成完成
            String localScreenshotPath = screenshotFuture.get();
            if (StrUtil.isBlank(localScreenshotPath)) {
                log.warn("生成网页截图失败，返回null以支持默认图片策略，URL={}", webUrl);
                return null;
            }

            // 上传截图到 COS
            String cosUrl = uploadScreenshotToCos(localScreenshotPath);
            if (StrUtil.isNotBlank(cosUrl)) {
                log.info("截图生成并上传成功，URL：{}", cosUrl);
            } else {
                log.warn("上传截图到COS失败，返回null以支持默认图片策略");
            }
            return cosUrl;
            
        } catch (Exception e) {
            log.error("异步截图服务异常，URL={}，返回null以支持默认图片策略", webUrl, e);
            return null; // 容错处理，返回null支持默认图片
        }
    }

    /**
     * 上传截图到对象存储
     *
     * @param localScreenshotPath 本地截图路径
     * @return 对象存储访问URL，失败返回null
     */
    private String uploadScreenshotToCos(String localScreenshotPath) {
        if (StrUtil.isBlank(localScreenshotPath)) {
            return null;
        }
        
        File screenshotFile = new File(localScreenshotPath);
        if (!screenshotFile.exists()) {
            log.error("截图文件不存在: {}", localScreenshotPath);
            return null;
        }
        
        try {
            // 生成 COS 对象键
            String fileName = UUID.randomUUID().toString().substring(0, 8) + "_compressed.jpg";
            String cosKey = generateScreenshotKey(fileName);
            
            // 上传到COS
            String cosUrl = cosManager.uploadFile(cosKey, screenshotFile);
            
            return cosUrl;
        } finally {
            // 自动清理本地文件，确保资源清理
            cleanupLocalFile(localScreenshotPath);
        }
    }

    /**
     * 生成截图的对象存储键
     * 格式：/screenshots/2025/07/31/filename.jpg
     */
    private String generateScreenshotKey(String fileName) {
        String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        return String.format("/screenshots/%s/%s", datePath, fileName);
    }

    /**
     * 清理本地文件和父目录
     *
     * @param localFilePath 本地文件路径
     */
    private void cleanupLocalFile(String localFilePath) {
        if (StrUtil.isBlank(localFilePath)) {
            return;
        }
        
        try {
            File localFile = new File(localFilePath);
            if (localFile.exists()) {
                FileUtil.del(localFile);
                log.debug("清理本地截图文件: {}", localFilePath);
                
                // 清理空的父目录（防止临时目录积累）
                File parentDir = localFile.getParentFile();
                if (parentDir != null && parentDir.exists() && parentDir.list().length == 0) {
                    FileUtil.del(parentDir);
                    log.debug("清理空目录: {}", parentDir.getPath());
                }
            }
        } catch (Exception e) {
            log.warn("清理本地文件异常: {}", localFilePath, e);
        }
    }
}
